/*
 * Copyright (C) 2025 Tsingteng MicroSystem
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file ee_int.h
 * @brief 定义用于模块内访问的Nfcee相关接口
 */

#ifndef _EE_INT_H_
#define _EE_INT_H_

#include "nci_feature.h"
#include "nci_base.h"
#include "nfa_routing.h"
#include "nfa_ee.h"

#if IS_FEATURE_ON(NCI_FEATURE_EE)

#define NCI_DH_NFCEE_ID  (0x00)
#define NCI_T4T_NFCEE_ID (0x10)

#define NCI_MAX_NFCEE_CBACKS  (3)

#if IS_FEATURE_ON(NCI_FEATURE_EE_DH)
    #define EE_IS_SUPPORT_DH 1
    #define NCI_MAX_NFCEE_SIZE (NCI_MAX_NFCEE_SUPPORT + 1)  /* NFCEEs and DH */
    #define NCI_NFCEE_DH NCI_MAX_NFCEE_SUPPORT
#else
    #define EE_IS_SUPPORT_DH 0
    #define NCI_MAX_NFCEE_SIZE NCI_MAX_NFCEE_SUPPORT
#endif

#define ROUTE_FIXED_ENTRY_SIZE 0x29 /* 0x29 = tech size(5*3) + proto size(5*2) + sc(6*2) + empty aid(4) */

/**
 * @brief EE状态
 *
 * @note 通过ee_mode_set可以改变EE状态
 */
typedef enum {
    NCI_NFCEE_ENABLED = 0x00,
    NCI_NFCEE_DISABLED = 0x01,
    NCI_NFCEE_UNRESPONSIVE = 0x02,
} tNCI_EE_STATUS;

/**
 * @brief EE信息
 *
 * @note 通过ee_get_info可以获取
 */
typedef struct {
    uint8_t ee_id;
    bool using_hci;
    tNCI_EE_STATUS status;
} tNCI_EE_INFO;

/**
 * @brief ee_mode_set设置EE状态的参数
 */
typedef enum {
    NCI_NFCEE_MODE_DISABLE = 0x00,
    NCI_NFCEE_MODE_ENABLE = 0x01,
} tNCI_EE_MODE;

/**
 * @brief ee_power_and_link_ctrl设置EE power&link的参数
 */
typedef enum {
    NCI_EE_POWER_AND_LINK_CFG_NFCC_DECIDE = 0x00,
    NCI_EE_POWER_AND_LINK_CFG_POWER_ALWAYS_ON = 0x01,
    NCI_EE_POWER_AND_LINK_CFG_LINK_WITH_POWER = 0x02,
    NCI_EE_POWER_AND_LINK_CFG_ALL_ALWAYS_ON = 0x03,
} tNCI_EE_POWER_AND_LINK_CFG;

typedef struct {
    uint8_t ee_id;
    tNCI_RF_PROTOCOL la_protocol;
    tNCI_RF_PROTOCOL lb_protocol;
    tNCI_RF_PROTOCOL lf_protocol;
} tNCI_EE_DISCOVER_REQ_INFO;

typedef struct {
    uint8_t ee_num;
    tNCI_EE_DISCOVER_REQ_INFO infos[NCI_MAX_NFCEE_SIZE];
} tNCI_EE_DISCOVER_REQ;

typedef union  {
    tNCI_EE_DISCOVER_REQ discover_req;
} tNCI_EE_EVT_DATA;

/**
 * @brief EE模块事件
 *
 * @note 通过ee_register_cback注册回调后，调用方在EE状态变化时，可以收到这里的事件
 */
typedef enum {
    NCI_EE_DISCOVER_REQ_EVT,
    NCI_EE_RECOVERY,
} tNCI_EE_EVT;

typedef void(*tNCI_EE_CBACK)(tNCI_EE_EVT event, tNCI_EE_EVT_DATA* p_data);

typedef struct {
    /**
     * @brief EXT EE的ID
     */
    uint8_t id;
    /**
     * @brief EXT EE初始化函数
     * @param p_cfg 初始化参数结构体指针，可在此结构体中取模块需要的初始化参数
     * @return 成功返回NCI_STATUS_OK, 失败返回对应的错误码
     */
    tNCI_STATUS (*init)();
    /**
     * @brief EXT EE去初始化函数
     * @return 成功返回NCI_STATUS_OK, 失败返回对应的错误码
     */
    tNCI_STATUS (*deinit)();
} tNCI_EXTERN_EE;

/**
 * @brief 获取EE模块中记录的所有NFCEE的信息，不包括DH
 *
 * @param ee_num 传入指针，函数执行成功后返回的实际nfcee信息的数量
 * @param infos  传入指针，函数执行成功后返回的实际nfcee信息
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS ee_get_info(uint8_t* ee_num, tNCI_EE_INFO* infos);

/**
 * @brief 获取EE模块中记录的所有NFCEE的discovery requset信息
 *
 * @param req 传入指针，函数执行成功后返回所有NFCEE的discovery requset信息
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS ee_get_discovery_req(tNCI_EE_DISCOVER_REQ* req);

/**
 * @brief 激活或者去激活EE
 *
 * @param ee_id 目标EE的id
 * @param mode  期望设置的ee状态
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS ee_mode_set(uint8_t ee_id, tNCI_EE_MODE mode);

/**
 * @brief 设置EE的power and link状态
 *
 * @param ee_id 目标EE的id
 * @param cfg   期望设置的power and link状态
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS ee_power_and_link_ctrl(uint8_t ee_id, tNCI_EE_POWER_AND_LINK_CFG cfg);

/**
 * @brief 向NFCEE管理模块中注册ee模块事件回调，收到EE管理模块在收到ee模块事件后会触发回调给调用方
 *
 * @param cb 调用方设置的回调，用于接收来自ee管理模块的事件和数据
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS ee_register_cback(tNCI_EE_CBACK cb);

/**
 * @brief 向NFCEE管理模块取消注册ee模块事件回调
 *
 * @param cb 调用方先前调用ee_register_cback设置的回调
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS ee_deregister_cback(tNCI_EE_CBACK cb);
#if IS_FEATURE_ON(NCI_FEATURE_ROUTING)
/**
 * @brief 向路由表中添加AID路由
 *
 * @note 如果同一个AID已经存在，则更新路由表中的AID路由
 *
 * @param ee_id 路由项所属的NFCEE ID
 * @param power_state 路由项的电源状态
 * @param aid AID，NULL表示AID*
 * @param aid_len AID长度
 *
 * @return 添加成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_add_aid(uint8_t ee_id, tNCI_EE_PWR_STATE power_state, uint8_t *aid, uint8_t aid_len, tNCI_AID_INFO aid_info);
/**
 * @brief 删除路由表中的AID路由
 *
 * @param aid AID，NULL表示AID*
 * @param aid_len AID长度
 *
 * @return 删除成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_remove_aid(uint8_t *aid, uint8_t aid_len);
/**
 * @brief 添加SystemCode类型路由
 *
 * @param ee_id 路由项所属的NFCEE ID
 * @param power_state 路由项的电源状态
 * @param system_code SystemCode编码，高字节在前
 *
 * @return 添加成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_add_sys_code(uint8_t ee_id, tNCI_EE_PWR_STATE power_state, uint16_t system_code);
/**
 * @brief 移除SystemCode类型路由
 *
 * @param system_code 需要移除的SystemCode编码，高字节在前
 *
 * @return 删除成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_remove_sys_code(uint16_t system_code);
/**
 * @brief 添加Tech类型路由
 *
 * @param ee_id 路由项所属的NFCEE ID
 * @param power_state 路由项的电源状态
 * @param tech Tech类型
 *
 * @return 添加成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_add_tech(uint8_t ee_id, tNCI_EE_PWR_STATE power_state, tNCI_RF_TECH tech);
/**
 * @brief 移除Tech类型路由
 *
 * @param tech 需要移除的Tech类型
 *
 * @return 删除成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_remove_tech(tNCI_RF_TECH tech);
/**
 * @brief 添加Protocol类型路由
 *
 * @param ee_id 路由项所属的NFCEE ID
 * @param power_state 路由项的电源状态
 * @param protocol Protocol类型
 *
 * @return 添加成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_add_protocol(uint8_t ee_id, tNCI_EE_PWR_STATE power_state, tNCI_RF_PROTOCOL protocol);
/**
 * @brief 移除Protocol类型路由
 *
 * @param protocol 需要移除的Protocol类型
 *
 * @return 删除成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_remove_protocol(tNCI_RF_PROTOCOL protocol);
/**
 * @brief 清除指定类型的所有路由
 *
 * @param type 路由类型
 *
 * @return 清除成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_clear(tNCI_ROUTING_ENTRY_TYPE type);
/**
 * @brief 清除所有路由
 *
 * @return 清除成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_clear_all();
/**
 * @brief 更新路由表，将路由表中的路由项发送给NFCC
 *
 * @return 更新成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_commit();
#if IS_FEATURE_ON(NCI_FEATURE_EE_DH)
/**
 * @brief 设置secure NFC状态
 *
 * @note secure NFC状态下，只有screen on unlocked状态下的DH才能被路由到
 * @note 不影响Offhost的路由
 * @note 需要commit routing后生效
 * @param enable 是否开启secure NFC
 *
 * @return 设置成功返回NCI_STATUS_OK，否则返回对应错误码
 */
tNCI_STATUS ee_route_set_secure_nfc(bool enable);
#endif // IS_FEATURE_ON(NCI_FEATURE_EE_DH)

#endif // IS_FEATURE_ON(NCI_FEATURE_ROUTING)
#endif /* NCI_FEATURE_EE */
#endif /* _EE_INT_H_ */